<script setup lang="ts">
import { ref, computed } from 'vue';
import { useMouseInElement } from '@vueuse/core';
import gsap from 'gsap';
import type { Photo } from '../types';

const props = defineProps<{
  photos: Photo[];
  maxDisplay?: number;
}>();

const stackRef = ref<HTMLElement | null>(null);
const { elementX, elementY, isOutside } = useMouseInElement(stackRef);
const isDragging = ref(false);
const startX = ref(0);
const startY = ref(0);
const currentIndex = ref(0);

const displayPhotos = computed(() => {
  const start = currentIndex.value;
  const max = props.maxDisplay || 3;
  const photos = [...props.photos];
  const rotated = [...photos.slice(start), ...photos.slice(0, start)];
  return rotated.slice(0, max).reverse();
});

const getInitialOffset = (index: number) => {
  const totalPhotos = displayPhotos.value.length;
  const reverseIndex = totalPhotos - 1 - index;
  return {
    x: reverseIndex * 3,
    y: reverseIndex * 4,
    rotate: (reverseIndex * 2 - 2) * -1,
    scale: 1 - (reverseIndex * 0.05)
  };
};

const getPhotoStyle = (index: number) => {
  const { x, y, rotate, scale } = getInitialOffset(index);
  
  if (isOutside.value || !isDragging.value) {
    return {
      transform: `
        translate3d(${x}px, ${y}px, 0)
        rotate(${rotate}deg)
        scale(${scale})
      `,
      zIndex: index
    };
  }

  const centerX = stackRef.value ? stackRef.value.offsetWidth / 2 : 0;
  const centerY = stackRef.value ? stackRef.value.offsetHeight / 2 : 0;
  const deltaX = elementX.value - centerX;
  const deltaY = elementY.value - centerY;
  const distance = Math.hypot(deltaX / centerX, deltaY / centerY);
  const rotation = (deltaX / centerX) * 15;
  const lift = Math.max(0, 1 - distance);
  
  const springX = x + (deltaX * 0.1 * (1 - index / displayPhotos.value.length));
  const springY = y + (deltaY * 0.1 * (1 - index / displayPhotos.value.length));
  const springRotate = rotate + (rotation * (1 - index / displayPhotos.value.length));
  
  return {
    transform: `
      translate3d(${springX}px, ${springY - lift * 20}px, ${lift * 30}px)
      rotate(${springRotate}deg)
      scale(${scale + lift * 0.05})
    `,
    zIndex: index
  };
};

const handleMouseDown = (event: MouseEvent) => {
  isDragging.value = true;
  startX.value = event.clientX;
  startY.value = event.clientY;
};

const handleMouseUp = () => {
  isDragging.value = false;
  displayPhotos.value.forEach((_, index) => {
    const element = stackRef.value?.children[index] as HTMLElement;
    if (element) {
      const { x, y, rotate, scale } = getInitialOffset(index);
      gsap.to(element, {
        x,
        y,
        rotation: rotate,
        scale,
        duration: 0.6,
        ease: 'elastic.out(1, 0.5)'
      });
    }
  });
};

const handleMouseLeave = () => {
  if (isDragging.value) {
    handleMouseUp();
  }
};

const handleClick = () => {
  if (!isDragging.value) {
    const nextIndex = (currentIndex.value + 1) % props.photos.length;
    currentIndex.value = nextIndex;
    
    // Animate the transition
    displayPhotos.value.forEach((_, index) => {
      const element = stackRef.value?.children[index] as HTMLElement;
      if (element) {
        const { x, y, rotate, scale } = getInitialOffset(index);
        gsap.to(element, {
          x,
          y,
          rotation: rotate,
          scale,
          duration: 0.4,
          ease: 'power2.out'
        });
      }
    });
  }
};
</script>

<template>
  <div
    ref="stackRef"
    class="photo-stack relative w-full aspect-[3/2] cursor-pointer"
    @mousedown="handleMouseDown"
    @mouseup="handleMouseUp"
    @mouseleave="handleMouseLeave"
    @click="handleClick"
  >
    <div
      v-for="(photo, index) in displayPhotos"
      :key="photo.id"
      class="photo-stack-item absolute inset-0"
      :style="getPhotoStyle(index)"
    >
      <div class="photo-wrapper">
        <img
          :src="photo.url"
          :alt="photo.title"
          class="w-full h-full object-cover rounded-xl"
          draggable="false"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
.photo-stack {
  perspective: 1200px;
  transform-style: preserve-3d;
  user-select: none;
}

.photo-stack-item {
  transform-origin: center;
  will-change: transform;
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  pointer-events: none;
}

.photo-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

.photo-wrapper img {
  border: 3px solid rgb(255, 255, 255);
  box-shadow: 
    0 1px 1px rgba(0,0,0,0.12),
    0 2px 2px rgba(0,0,0,0.12),
    0 4px 4px rgba(0,0,0,0.12),
    0 8px 8px rgba(0,0,0,0.12);
}

.photo-stack:hover .photo-stack-item {
  transition-duration: 0.15s;
}

@media (max-width: 768px) {
  .photo-stack {
    perspective: 800px;
  }
}
</style>